/**
 * 由于IE7 IE8等浏览器不支持es5的新方法, es5-array.js提供的兼容代码. 已在IE7 IE8下测试通过.
 * 
 * 以下方法IE7 IE8均不支持, 进行了兼容处理: 
 * forEach
 * map
 * filter
 * some
 * every
 * indexOf
 * lastIndexOf
 * reduce
 * reduceRight
 * 
 * 术语:
 * 空项, 指的是数组定义时两个连续的 ,, 形成的一个空项, 或者是通过 delete删除的项.
 */

/**
 * 排除空项
 */
if (typeof Array.prototype.forEach != "function") {
	Array.prototype.forEach = function(fn, context) {
		if (typeof fn === "function") {
			for ( var k = 0, length = this.length; k < length; k++) {
				// Object.prototype.hasOwnProperty.call(this, k)
				// this.propertyIsEnumerable(k)
				this.hasOwnProperty(k) && fn.call(context, this[k], k, this);
			}
		}
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.map != "function") {
	Array.prototype.map = function(fn, context) {
		var arr = [];
		if (typeof fn === "function") {
			for ( var k = 0, length = this.length; k < length; k++) {
				this.hasOwnProperty(k) 
						&& arr.push(fn.call(context, this[k], k, this));
			}
		}
		return arr;
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.filter != "function") {
	Array.prototype.filter = function(fn, context) {
		var arr = [];
		if (typeof fn === "function") {
			for ( var k = 0, length = this.length; k < length; k++) {
				this.hasOwnProperty(k) 
						&& fn.call(context, this[k], k, this) && arr.push(this[k]);
			}
		}
		return arr;
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.some != "function") {
	Array.prototype.some = function(fn, context) {
		var passed = false;
		if (typeof fn === "function") {
			for ( var k = 0, length = this.length; k < length; k++) {
				if (passed === true) {
					break;
				}
				this.hasOwnProperty(k)
						&& (passed = !!fn.call(context, this[k], k, this));
			}
		}
		return passed;
	};
}

/**
 * 忽略空项
 */
if (typeof Array.prototype.every != "function") {
	Array.prototype.every = function(fn, context) {
		var passed = true;
		if (typeof fn === "function") {
			for ( var k = 0, length = this.length; k < length; k++) {
				if (passed === false) {
					break;
				}
				this.hasOwnProperty(k)
						&& (passed = !!fn.call(context, this[k], k, this));
			}
		}
		return passed;
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.indexOf != "function") {
	Array.prototype.indexOf = function(searchElement, fromIndex) {
		var index = -1;
		fromIndex = fromIndex * 1 || 0;

		for ( var k = 0, length = this.length; k < length; k++) {
			if (this.hasOwnProperty(k) && k >= fromIndex && this[k] === searchElement) {
				index = k;
				break;
			}
		}
		return index;
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.lastIndexOf != "function") {
	Array.prototype.lastIndexOf = function(searchElement, fromIndex) {
		var index = -1, length = this.length;
		fromIndex = fromIndex * 1 || length - 1;

		for ( var k = length - 1; k > -1; k--) {
			if (this.hasOwnProperty(k) && k <= fromIndex && this[k] === searchElement) {
				index = k;
				break;
			}
		}
		return index;
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.reduce != "function") {
	Array.prototype.reduce = function(callback, initialValue) {
		var previous = initialValue, k = 0, length = this.length;
		if (typeof initialValue === "undefined") {
			previous = this[0];
			k = 1;
		}

		if (typeof callback === "function") {
			for (; k < length; k++) {
				this.hasOwnProperty(k)
						&& (previous = callback(previous, this[k], k, this));
			}
		}
		return previous;
	};
}

/**
 * 排除空项
 */
if (typeof Array.prototype.reduceRight != "function") {
	Array.prototype.reduceRight = function(callback, initialValue) {
		var length = this.length, k = length - 1, previous = initialValue;
		if (typeof initialValue === "undefined") {
			previous = this[length - 1];
			k--;
		}
		if (typeof callback === "function") {
			for (; k > -1; k--) {
				this.hasOwnProperty(k)
						&& (previous = callback(previous, this[k], k, this));
			}
		}
		return previous;
	};
}